package com.amumu.drama.common.commpont.idgenerator;


import com.amumu.drama.common.modules.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public final class IdGenerator {

    private static RedisService redisService;

    @Value("${redis.key.orderId}")
    private String REDIS_KEY_ORDER_ID;
    @Value("${redis.database}")
    private String REDIS_DATABASE;

    @Autowired
    public void setJedisTemplate(RedisService redisService) {
        IdGenerator.redisService = redisService;
    }

    /**
     * <pre>
     * 支付订单(19)           yyyyMMddHHmmss + milliTime(3位) + userId后两位
     * 购买商品订单(19)       yyyyMMddHHmmss + milliTime(3位) + userId后两位
     * 兑换券 (20)            "T" + yyyyMMddHHmmss + milliTime(3位) + userId后两位
     * 用户子帐号(19)         "1"/"2" + yyMMddHHmmss + 精确秒数后4位  + userId后两位
     * </pre>
     */
    public static final TimebasedIdGenerator[] timebasedIdGenerator_A = new TimebasedIdGenerator[100];// 按userId % 100 分成100个生成器,提高并发性 -> 10w并发

    public static final TimebasedIdGenerator[] timebasedIdGenerator_B = new TimebasedIdGenerator[100];// 100w并发

    public static final char[] CHARACTER = {
            'a',
            'b',
            'c',
            'd',
            'e',
            'f',
            'g',
            'h',
            'i',
            'j',
            'k',
            'l',
            'm',
            'n',
            'o',
            'p',
            'q',
            'r',
            's',
            't',
            'u',
            'v',
            'w',
            'x',
            'y',
            'z'
    };

    /** 订单号通过Redis去重的过期时间，单位:秒 */
    private static final int ORDER_ID_NX_EXPIRE_SECONDS = 10;


    static {
        for (int i = 0; i < 100; i++) {
            timebasedIdGenerator_A[i] = new TimebasedIdGenerator(3, true);
            timebasedIdGenerator_B[i] = new TimebasedIdGenerator(3, false);
        }
    }

    private IdGenerator() {
    }

    private static long nextIdA(long userId) {
        int idx = (int) (userId % 100);
        return timebasedIdGenerator_A[idx].nextLongId() * 100 + idx;
    }

    private static long nextIdB(long userId) {
        int idx = (int) (userId % 100);
        int suffix = 2000 + idx;
        return timebasedIdGenerator_B[idx].nextLongId() * 10000 + suffix;
    }

    /**
     * 给支付的订单id
     */
    public static long getPayOrderId(long userId) {
        return nextIdA(userId);
    }

    /**
     * 订单号是否会冲突
     *
     * @param orderId 订单号
     * @return true:冲突，需重新生成；false:无冲突，可以使用
     */
    private static boolean _hasConflict(long orderId) {
        if (redisService == null) {
            return false;
        }
        Boolean absent = redisService.setIfAbsent("orderId:nx_" + orderId, "1", ORDER_ID_NX_EXPIRE_SECONDS);
        return absent != null && !absent;
    }

    /**
     * 购买商品的id
     */
    public static long getOrderId(long userId) {
        long orderId;
        do {
            orderId = nextIdA(userId);
        } while (_hasConflict(orderId));
        return orderId;
    }

    /**
     * 购买商品的id
     */
    public static long getBookingId(long userId) {
        return nextIdB(userId);
    }

    /**
     * 单纯获取不重复的ID
     */
    public static long getId() {
        return timebasedIdGenerator_A[0].nextLongId();
    }

}
